﻿using System;
using System.Data;
using System.Diagnostics;
using System.IO;
using System.Runtime.Serialization;
using System.Windows.Forms;
using System.Xml.Serialization;
using CXMLStudioIDE.DataAccessLayer;
using CXMLStudioIDE.Views;
using CXMLStudioIDE.WinFormsUI.CXMLStudioControls;
using System.Xml;

namespace CXMLStudioIDE.Presenters
{
    public class GoldEntryPresenter
    {
        private readonly IGoldEntryView _View;

        public GoldEntryPresenter(IGoldEntryView view)
        {
            this._View = view;
            view.OnFormClosing += OnFormClosing;
            view.OnInstancePreviewClicked += OnInstancePreview;
            view.OnSaveInstanceClicked += OnSaveEntityInstance;
            view.OnLoadInstanceClicked += OnLoadInstance;
            view.OnAddToParentClicked += OnAddToParent;
            view.OnFileSelected += OnFileSelected;
        }

        public void OnGoldFormCompleted(object sender)
        {
        }

        private XmlSerializerNamespaces GetNamespaces()
        {
            XmlSerializerNamespaces ns;
            ns = new XmlSerializerNamespaces();
            ns.Add("xs", "http://www.w3.org/2001/XMLSchema");
            ns.Add("xsi", "http://www.w3.org/2001/XMLSchema-instance");
            ns.Add(_View.EntityType.Namespace, "http://SetNamespacehere");
            return ns;
        }

        public void SerializeInstanceToXmlString(object instance)
        {
            try
            {
                var serializer = new XmlSerializer(instance.GetType());
                var sw = new StringWriter();
                serializer.Serialize(sw, instance, GetNamespaces());
                _View.xml_SerializedEntity = sw.ToString();
            }
            catch (InvalidOperationException ioe)
            {
                //MessageBox.Show(ioe.Message + "\n" + ioe.StackTrace +
                //"\n" + ioe.InnerException, "CXMLStudio", MessageBoxButtons.OK, MessageBoxIcon.Error);
                Debug.WriteLine(ioe.Message + "\n" + ioe.StackTrace + "\n" + ioe.InnerException + "\n");
            }
            catch (SerializationException sex)
            {
                MessageBox.Show(sex.Message, "CXMLStudio", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void OnInstancePreview(object sender, EventArgs e)
        {
            if (_View.EntityInstance != null)
            {
                SerializeInstanceToXmlString(_View.EntityInstance);
                _View.ParentMainForm.NewTextFile(_View.xml_SerializedEntity);
            }
        }

        public void OnAddToParent(object sender, EventArgs e)
        {
            CXMLTreeNode calling = _View.CallingCXMLNode;
            string propname = null;
            if (calling != null)
            {
                switch (calling.Name)
                {
                    case "Places":
                        propname = "Places.Place";
                        break;
                    case "Risks":
                        propname = "Risks.Risk";
                        break;
                    case "Coverages":
                        propname = "Coverages.Coverage";
                        break;
                }
            }
            if (propname != null)
            {
                _View.CallingGoldForm.AddInstance(_View.EntityInstance, propname,
                                                 _View.RootCXMLNode.Clone() as CXMLTreeNode);
                _View.ParentMainForm.SetActiveDocument(_View.CallingGoldForm);
            }
        }

        public void OnLoadInstance(object sender, EventArgs e)
        {
            if (_View.SelectedItem != null)
            {
                _View.xml_SerializedEntity = ((DataRowView) _View.SelectedItem).Row["xml_SerializedEntity"].ToString();
                SetEntityInstance();
                _View.EnableAddInstanceButton();
                _View.EntityInstanceDescription = ((DataRowView)_View.SelectedItem).Row["EntityInstanceDescription"].ToString();
                if(!string.IsNullOrEmpty(_View.EntityInstanceDescription))
                {
                    _View.RootCXMLNode.GoldInstanceDescription = _View.EntityInstanceDescription;
                }
            }
        }
        private void SetEntityInstance()
        {
            if (!string.IsNullOrEmpty(_View.xml_SerializedEntity) &&
            _View.EntityType != null)
            {
                _View.EntityInstance = Common.Common.FromXml(_View.xml_SerializedEntity, _View.EntityType);
                _View.SetBindingSource();
            }
        }

        public void OnSaveEntityInstance(object o, EventArgs e)
        {
            if (_View.EntityInstance != null)
            {
                SerializeInstanceToXmlString(_View.EntityInstance);
                string sZ_InstanceName = null;
                string value = _View.RootBusinessEntity.Name + " - " +
                               _View.RootBusinessEntity.EntityType.EntityTypeContextName + " - " +
                               _View.RootBusinessEntity.EntityVersion.FullVersion;
                if (Common.Common.InputBox("Save Entity Instance", "New instance name:", ref value) == DialogResult.OK)
                {
                    sZ_InstanceName = value;

                    if (!string.IsNullOrEmpty(_View.xml_SerializedEntity) &&
                        _View.EntityID > 0)
                    {
                        var dal = new CXMLStudioDAL();
                        dal.SaveEntityInstance(_View.EntityID, _View.xml_SerializedEntity, sZ_InstanceName);
                        _View.LoadInstanceCombo(_View.EntityID);
                    }
                }
            }
        }

        private void OnFormClosing(object sender, FormClosingEventArgs e)
        {
            _View.ReleaseBindings();
        }

        private void OnFileSelected(object sender, string filename)
        {
            ReadFile(filename);
            SetEntityInstance();
        }

        private void ReadFile(string filename)
        {
            try
            {
                // The main form and items in the component tray will be at the
                // same level, so we have to create a higher super-root in order
                // to construct our XmlDocument.
                StreamReader sr = new StreamReader(filename);
                string cleandown = sr.ReadToEnd();
                XmlDocument doc = new XmlDocument();
                doc.LoadXml(cleandown);
                _View.xml_SerializedEntity = doc.OuterXml;
            }
            catch (Exception ex)
            {
                _View.xml_SerializedEntity = null;
                MessageBox.Show("Error while reading file:" + filename + 
                    "\n" + ex.Message, "CXMLStudio", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
    }
}